D) Variadic Template

#include <iostream>
template <typename T>
void print(T arg){
std::cout<<arg<<std::endl;
}
template <typename T, typename ...Types>
void print(T arg, Types... args){
std::cout<<arg<<", ";
print(args...);
}
int main(void){
print(1, 3.1, "abc");
print(1, 2, 3, 4, 5, 6, 7);
return 0;
}

1, 3.1, abc

1, 2, 3, 4, 5, 6, 7

Pack Expansion
Parameter Pack을 사용하는 패턴에 “ … “를 붙이면 해당 패턴이 ‘ , ‘ 구분자로 확장되는 형태
ex) args가 1, 2, 3인 경우
args…        1, 2, 3
(-args)…        0, 1, 2

func(args)        func(1), func(2), func(3)
func(args…)        func(1, 2, 3)
func2(func(args…))        func2(func(1, 2, 3))
func2(func(args)…))        func2(func(1), func(2), func(3))
Parameter pack
template <typename... Types>
struct Tuple {};
Tuple<> t0;
Tuple<int> t1;
Tuple<int, float> t2;
Variadic Template 이 아닌 일반 함수에서도 ‘ … ‘ 연산자를 사용할 수 있다.
#include <iostream>
using namespace std;
void PrintNums(int args, ...){
cout<<"args: "<<args<<endl;
}
int main(void){
PrintNums(1, 1);
PrintNums(2, 1, 2);
PrintNums(3, 1, 2, 3);
return 0;
}

args: 1

args: 2

args: 3

각 원소의 첫 번째 args만 출력
C에서는 <stdarg.h> 헤더의 아래 함수로 이를 구현한다.
va_start(va_list, lastfix);
va_arg(va_list, type);
va_end(va_lis);
Variable with c header <stadarg.h>
#include <iostream>
#include <cstdarg>
using namespace std;
void PrintNums(int args, ...){
va_list ap;
va_start(ap, args);
for(int i=0; i<args; i++){
int n=va_arg(ap, int);
cout<<"args "<<args<<": "<<n<<endl;
}
va_end(ap);
cout<<endl;
}
int main(void){
PrintNums(1, 1);
PrintNums(2, 1, 2);
PrintNums(3, 1, 2, 3);
return 0;
}

args 1: 1


args 2: 1

args 2: 2


args 3: 1

args 3: 2

args 3: 3